﻿@using Seal.Model
@using Seal.Helpers
@{
    Report report = Model;
    ReportView view = report.CurrentView;
    ReportView modelView = report.CurrentModelView;
    ReportModel reportModel = modelView.Model;
    ResultPage page = report.CurrentPage;
    if (page == null) { return; }
    var series = page.Series.Where(i => i.Element.Nvd3Serie != NVD3SerieDefinition.None).OrderBy(i => i, new ResultSerieComparer());
}

@if (reportModel.HasNVD3Serie && series.Count() > 0 && modelView.GetBoolValue("show_charts"))
{
    <!--Chart NVD3-->
    bool chartOk = false;
    var axisCount = view.GetNumericValue("nvd3_xaxis_count");
    string chartId = "cnv" + Guid.NewGuid().ToString().Replace("-", "");
    if (modelView.InitPageChart(page))
    {
        var xLabels = axisCount > 0 ? string.Join(",", page.ChartXLabels.Split(',').Take(axisCount)) : page.ChartXLabels;
        <div id='@chartId' style="page-break-inside:avoid; position: relative; @Helper.AddIfNotEmpty("width:", view.GetValue("nvd3_chart_contwidth"), ";")@Helper.AddIfNotEmpty("height:", view.GetValue("nvd3_chart_contheight"), ";")">
            <svg style="@Helper.AddIfNotEmpty("width:", view.GetValue("nvd3_chart_width"), ";")@Helper.AddIfNotEmpty("height:", view.GetValue("nvd3_chart_height"), ";")" />
        </div>
        <script>
            $(document).ready(function () {
                nv.addGraph(function () {
                    var series = new Array();
                    @foreach (ResultSerie serie in series)
                    {
                        string multiChartOption = (reportModel.ExecNVD3ChartType == "multiChart" ? string.Format(",type:'{0}',yAxis:{1}", serie.NVD3MultiChartType, ((int)serie.Element.YAxisType + 1)) : "");
                        var data = axisCount > 0 ? string.Join("},{", serie.ChartXYSerieValues.Split(new string[] { "},{" }, StringSplitOptions.None).Take(axisCount)) + "}" : serie.ChartXYSerieValues;

                        <text>
                            series.push({ key: '@Raw(Helper.ToJS(serie.SerieDisplayName))', values: [@Raw(data)] @Raw(multiChartOption) });
                        </text>
                    }

                    var chartType = '@reportModel.ExecNVD3ChartType';
                    var xLabels = [@Raw(xLabels)];
                    var XValueFormatter = function (value) {
                        if (@Helper.ToJS(reportModel.ExecChartIsNumericAxis)) return d3.format('@Raw(Helper.ToJS(reportModel.ExecD3XAxisFormat))')(value).valueFormat();
                        if (@Helper.ToJS(reportModel.ExecChartIsDateTimeAxis)) return d3.timeFormat('@Raw(Helper.ToJS(reportModel.ExecD3XAxisFormat))')(new Date(value));
                        return xLabels[value];
                    }
                    var YPrimaryValueFormatter = function (value) {
                        if (@Helper.ToJS(reportModel.ExecAxisPrimaryYIsDateTime)) return d3.timeFormat('@Raw(Helper.ToJS(reportModel.ExecD3PrimaryYAxisFormat))')(new Date(value));
                        return d3.format('@Raw(Helper.ToJS(reportModel.ExecD3PrimaryYAxisFormat))')(value).valueFormat();
                    }
                    var YSecondaryValueFormatter = function (value) {
                        if (@Helper.ToJS(reportModel.ExecAxisSecondaryYIsDateTime)) return d3.timeFormat('@Raw(Helper.ToJS(reportModel.ExecD3SecondaryYAxisFormat))')(new Date(value));
                        return d3.format('@Raw(Helper.ToJS(reportModel.ExecD3SecondaryYAxisFormat))')(value).valueFormat();
                    }
                    var @chartId = nv.models.@(reportModel.ExecNVD3ChartType)();
                    var svg = d3.select('#@chartId svg');

                    var chartTitle = '@Raw(Helper.ToJS(modelView.GetTranslatedMappedLabel(view.GetValue("nvd3_chart_title"))))';

                    //Root Script
                    var colorsDef = "@view.GetValue("nvd3_colors")";
                    var colors = null;
                    if (colorsDef == "d3") colors = d3.scale.category@((reportModel.ExecNVD3ChartType == "pieChart" ? page.PrimaryXDimensions.Count : page.Series.Count) <= 10 ? "1" : "2")0().range();
                    else if (colorsDef == "d3b") colors = d3.scale.category20b().range();
                    else if (colorsDef == "d3c") colors = d3.scale.category20c().range();
                    else colors = @Raw(view.GetValue("nvd3_colors"));

                    var colorMappings = {@Raw(view.GetValue("nvd3_color_mappings"))};
                    if (@(!string.IsNullOrEmpty(view.GetValue("nvd3_color_mappings")) ? "true" : "false")) {
                        colors = (chartType == 'pieChart' ? [@Raw(xLabels)].map(function (i) { return colorMappings[i] }) : series.map(function (i) { return colorMappings[i.key] }));
                    }

                    (@chartId).color(colors);
                    //Axis format
                    if ((@chartId).xAxis != null && (@chartId).xAxis.tickFormat != null) (@chartId).xAxis.tickFormat(XValueFormatter);
                    if ((@chartId).yAxis != null && (@chartId).yAxis.tickFormat != null) (@chartId).yAxis.tickFormat(YPrimaryValueFormatter);
                    //For line with focus
                    if ((@chartId).x2Axis != null && (@chartId).x2Axis.tickFormat != null) (@chartId).x2Axis.tickFormat(XValueFormatter);
                    if ((@chartId).y2Axis != null && (@chartId).y2Axis.tickFormat != null) (@chartId).y2Axis.tickFormat(YPrimaryValueFormatter);
                    //For multichart
                    if ((@chartId).yAxis1 != null && (@chartId).yAxis1.tickFormat != null) (@chartId).yAxis1.tickFormat(YPrimaryValueFormatter);
                    if ((@chartId).yAxis2 != null && (@chartId).yAxis2.tickFormat != null) (@chartId).yAxis2.tickFormat(YSecondaryValueFormatter);

                    if ((@chartId).showXAxis != null) (@chartId).showXAxis(true);
                    if ((@chartId).showYAxis != null) (@chartId).showYAxis(true);

                    if ((@chartId).showDistX != null) (@chartId).showDistX(true);
                    if ((@chartId).showDistY != null) (@chartId).showDistY(true);

                    if (chartType != 'discreteBarChart') {
                        (@chartId).tooltip.headerFormatter(function (d, i) {
                            return (@chartId).xAxis.tickFormat()(d, i);
                        });
                        (@chartId).tooltip.keyFormatter(function (d, i) {
                            if (d == null) return '';
                            return nvd3TranslateTextAxis(d);
                        });

                        if (chartType == 'multiChart') { //specific tooltip handler
                            (@chartId).interactiveLayer.tooltip.contentGenerator(function (data) {
                                return nvd3TooltipGenerator(data, series, XValueFormatter, YPrimaryValueFormatter, YSecondaryValueFormatter);
                            });
                        }
                    }

                    //Margins
                    var margins = null;
                    if (chartType == 'multiBarHorizontalChart') margins = { left: 20 + 6*@page.AxisXLabelMaxLen, right: 22 };
                    else if (chartType != 'pieChart') margins = { left: 20 + 6*@page.AxisYPrimaryMaxLen, right: 50 + 6*@page.AxisYSecondaryMaxLen };
                    margins = @Raw(view.GetValue("nvd3_margins") != "auto" ? view.GetValue("nvd3_margins") : "margins");
                    if (margins) (@chartId).margin(margins);

                    //Options
                    var hideControls = (@Helper.ToJS(view.GetBoolValue("nvd3_hide_controls") || report.PrintLayout) || chartType == 'scatterChart' || (series.length == 1 && (chartType == 'multiBarChart' || chartType == 'multiBarHorizontalChart')));
                    if ((@chartId).showControls != null) (@chartId).showControls(!hideControls);
                    if ((@chartId).showLegend != null) (@chartId).showLegend(@view.GetBoolValueJS("nvd3_show_legend"));
                    if ((@chartId).stacked != null && (chartType == 'multiBarChart' || chartType == 'multiBarHorizontalChart')) (@chartId).stacked(@view.GetBoolValueJS("nvd3_bar_stacked")); //for Bar
                    if ((@chartId).reduceXTicks != null) (@chartId).reduceXTicks(!@view.GetBoolValueJS("chart_show_all_axis_labels"));

                    if ((@chartId).useInteractiveGuideline != null) (@chartId).useInteractiveGuideline(true);
                    if ((@chartId).interpolate != null) (@chartId).interpolate('cardinal');
                    if ((@chartId).staggerLabels != null) (@chartId).staggerLabels(true);

                    //Force axis ranges
                    if ((@chartId).forceX && @Helper.ToJS(view.HasValue("nvd3_xaxis_range"))) (@chartId).forceX([@view.GetValue("nvd3_xaxis_range")]);
                    if ((@chartId).forceY && @Helper.ToJS(view.HasValue("nvd3_yaxis_range"))) (@chartId).forceY([@view.GetValue("nvd3_yaxis_range")]);

                    //if ((@chartId).rotateLabels != null) (@chartId).rotateLabels(90);  //for Bar
                    //if ((@chartId).isArea != null) (@chartId).isArea(true); //for Line
                    //(@chartId).xAxis.showMaxMin(false);

                    (@chartId).navigations = [@Raw(page.ChartNavigations)];

                    //pie chart
                    if (chartType == 'pieChart') {
                        var total = 0;
                        series[0].values.forEach(function (d) {
                            total = total + d.y;
                        });
                        var labelType = '@view.GetValue("nvd3_pie_labeltype")';

                        (@chartId)
                            .x(function (d) { return xLabels[d.x] })
                            .showLabels(true)
                            .labelThreshold(@view.GetValue("nvd3_pie_labelthreshold")/100)
                            .donut(true)
                            .donutRatio(@view.GetValue("nvd3_pie_holeratio")/100)
                        ;

                        (@chartId).labelType(function (d) {
                            if (labelType == 'key') return XValueFormatter(d.data.x);
                            else if (labelType == 'percent') {
                                var percent = (d.endAngle - d.startAngle) / (2 * Math.PI);
                                return d3.format('.2%')(percent);
                            }
                            else if (labelType == 'value') return YPrimaryValueFormatter(d.value);
                            return "";
                        });

                        (@chartId).tooltip.valueFormatter(function (d) {
                            if (labelType == 'key' || labelType == 'none') return YPrimaryValueFormatter(d) + ' ('+ d3.format('.2%')(d/total) + ')';
                            else if (labelType == 'percent') return YPrimaryValueFormatter(d);
                            return d3.format('.2%')(d / total);
                        });
                    }

                    //Title
                    var svgJQ = $("#@chartId svg");
                    if (chartTitle.length > 0) {
                        svg.append('text')
                            .attr('class','chartTitleWrap')
                            .attr('x', Math.max(1, (svgJQ.width() - 7*chartTitle.length) / 2))
                            .attr('y', Math.max(svgJQ.height(), $("#@chartId").height()) + (chartType == 'lineWithFocusChart' ? 10 : -4))
                            .style('font-weight', 'bold')
                            .style('font-size', '14px')
                            .text(chartTitle);

                        //re-adjust title...
                        redrawNVD3Charts();
                    }

                    svg
                        .datum(@(reportModel.ExecNVD3ChartType != "pieChart" ? "series" : "series[0].values"))
                        .transition().duration(500)
                        .call(@chartId)
                        ;

                    if (nvd3Charts != null) nvd3Charts.push(@chartId);
                    nvd3TranslateAll("#@(chartId)");

                    if ((@chartId).pie && @Helper.ToJS(report.GenerateHTMLDisplay)) {
                        (@chartId).pie.dispatch.on("elementClick", function (e) {
                            var nav = @(chartId).navigations[e.data.x];
                            if (nav) showPopupNavMenu(e.event, nav, true, '@report.ExecutionGUID');
                        });
                    }
                    return @chartId;
                }
                    , function () {
                        d3.selectAll("#@chartId").on('click', function () {
                            nvd3TranslateAll("#@(chartId)");
                        });
                    });
            });//document.ready
        </script>
        chartOk = true;
    }
    if (!chartOk)
    {
        <div class="alert alert-danger" role="alert">
            @Raw(Helper.ToHtml(view.Error))
        </div>
        view.Error = "";
    }
}
